package com.huatai.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huatai.common.config.MinioAPI;
import com.huatai.common.entity.UserInfo;
import com.huatai.common.error.exception.ServiceException;
import com.huatai.common.util.*;
import com.huatai.user.constant.MinioBucket;
import com.huatai.user.constant.UserConstant;
import com.huatai.user.entity.User;
import com.huatai.user.entity.UserRole;
import com.huatai.user.mapper.UserMapper;
import com.huatai.user.service.UserRoleService;
import com.huatai.user.service.UserService;
import com.huatai.user.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.huatai.user.constant.UserConstant.*;


/**
 * @program: ht-system
 * @description: 用户管理
 * @author: songxiude
 * @create: 2023-02-02 16:17
 **/
@Service
@RefreshScope
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
	@Autowired
	private PasswordEncoder passwordEncoder;
	@Autowired
	private UserRoleService userRoleService;
	@Autowired
	private UserService userService;




	@Value("${ht.user.dfpassword}")
	private String dfpassword;

	@Autowired
	private MinioAPI minioAPI;

	/**
	 * 用户添加更新
	 *
	 * @param user
	 * @return
	 */
	public boolean saveUser(User user) {
		UserInfo userInfo = AuthUtil.getUser();
		user.setUpdateUserid(userInfo.getUserId());
		//如果不传主键id视为新增
		if (Objects.isNull(user.getId()) || user.getId().longValue() <= 0) {
			user.setCreateUserid(userInfo.getUserId());
			user.setId(IdWorker.getId());
			//创建用户时给默认密码
			user.setPassword(passwordEncoder.encode(dfpassword));
		}
		return saveOrUpdate(user);
	}

	/**
	 * 删除用户
	 *
	 * @param userId
	 * @return
	 */
	@Transactional(rollbackFor = {Exception.class})
	public boolean delUser(Long userId) {
		//admin用户不能删除
		if (userId.intValue() == 1) {
			throw new RuntimeException(SYSTEM_ADMIN_ERROR);
		}
		//删除该用户
		boolean remove = removeById(userId);
		//删除该用户的角色
		userRoleService.remove(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, userId));
		return remove;
	}

	/**
	 * 获取用户详细信息
	 *
	 * @param account
	 * @return
	 */
	public UserVo findUserInfo(String account) {
		try {
			//获取用户信息
			User user = getOne(Wrappers.<User>lambdaQuery().eq(User::getAccount, account).eq(User::getStatus, 0));
			if (Objects.isNull(user)) return null;
			UserVo userVo = BeanUtil.copy(user, UserVo.class);
			List<String> permissions;
			//如果该用户是超级管理员获取全部权限
			if (user.getIsAdmin().intValue() == 1) {
				permissions = baseMapper.selectAdminPers();
			} else {
				//获取用户权限列表
				permissions = baseMapper.selcetUserPermissions(user.getId());
			}
			//判断用户是否上传头像
			if(StringUtil.isNotBlank(user.getAvatar())){
				String signedUrl = minioAPI.getSignedUrl(MinioBucket.HUATAI_PUB_BUCKET, user.getAvatar(), 86400);
				userVo.setAvatar(signedUrl);
			}
			userVo.setPermissions(permissions);
			return userVo;
		}catch (Exception e){
			log.error(e.getMessage());
		}
		return null;
	}

	/**
	 * 根据查询条件获取用户列表信息
	 *
	 * @param userParamInfo
	 * @return
	 */
	public IPage<UserInfoVo> getUserList(UserParamInfo userParamInfo) {
		Page<UserInfoVo> page = PaginationUtils.getPage(userParamInfo.getPage(),userParamInfo.getSize());
		LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
		//过滤软删除
		queryWrapper.eq(User::getIsDeleted,0);
		//根据账号模糊查询
		queryWrapper.like(StringUtil.isNotBlank(userParamInfo.getAccount()),User::getAccount, userParamInfo.getAccount());
		//根据手机号查询
		queryWrapper.eq(StringUtil.isNotBlank(userParamInfo.getPhone()),User::getPhone, userParamInfo.getPhone());
		//根据部门查询
		if (userParamInfo.getDeptId() != null && userParamInfo.getDeptId().intValue() != 0) {
			queryWrapper.eq(User::getDeptId, userParamInfo.getDeptId());
		}
		queryWrapper.orderByDesc(User::getCreateTime);
		IPage<UserInfoVo> selectUserList = baseMapper.selectUserList(page, queryWrapper);
		return selectUserList;
	}

	/**
	 * 用户角色添加编辑
	 *
	 * @param userRoleParamVo
	 * @return
	 */
	@Transactional(rollbackFor = {Exception.class})
	public boolean userRoleAddEdit(UserRoleParamVo userRoleParamVo) {
		//判断是否是系统超级管理员
		if(userRoleParamVo.getUserId().longValue()==USER_ADMIN_ONE){
			throw new ServiceException("系统超级管理员无须设置");
		}
		//先删除之前的用户角色
		userRoleService.remove(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, userRoleParamVo.getUserId()));
		//组装新的用户角色并保存
		List<UserRole> roleList = new ArrayList<>();
		userRoleParamVo.getRoleIds().forEach(aLong -> {
			UserRole userRole = new UserRole();
			userRole.setUserId(userRoleParamVo.getUserId());
			userRole.setRoleId(aLong);
			roleList.add(userRole);
		});
		//判断是够设置超级管理员如果包含回设用户信息为超级管理员
		User user = userService.getOne(Wrappers.<User>lambdaQuery().eq(User::getId, userRoleParamVo.getUserId()));
		if (userRoleParamVo.getRoleIds().contains(1L) && user.getIsAdmin().intValue()==USER_ADMIN_ZERO){
			user.setIsAdmin(USER_ADMIN_ONE);
			userService.updateById(user);
		}
		//如果该用户之前是超级管理被设置为普通管理员回设用户信息为普通用户
		if(!userRoleParamVo.getRoleIds().contains(1L) && user.getIsAdmin().intValue()==USER_ADMIN_ONE){
			user.setIsAdmin(USER_ADMIN_ZERO);
			userService.updateById(user);
		}
		return userRoleService.saveBatch(roleList);
	}

	/**
	 * 获取登录用户菜单列表
	 *
	 * @return
	 */
	public List<PermissionVo> getUserPermissions() {
		//Long userId = AuthUtil.getUser().getUserId();
		UserInfo userInfo = AuthUtil.getUser();
		List<PermissionVo> userPermissions;
		//如果是超级管理员获取全部菜单列表
		if (userInfo.getIsAdmin().intValue() == USER_ADMIN_ONE) {
			userPermissions = baseMapper.getPermissions();
		} else {
			//获取用户资源权限
			userPermissions = baseMapper.getUserPermissions(userInfo.getUserId());
//			userPermissions = baseMapper.getPermissions();
		}
		if (CollectionUtil.isEmpty(userPermissions)) {
			return Collections.emptyList();
		}
		//递归组装新列表返回
		List<PermissionVo> collect = userPermissions.stream().filter(t -> t.getParentId() == 0).map(
			m -> {
				m.setChildren(getChildren(m, userPermissions));
				return m;
			}
		).collect(Collectors.toList());

		return collect;
	}


	/**
	 * 获取用户角色列表包含选中状态（前端回显使用）
	 *
	 * @return
	 */
	public List<RoleVo> getUserRoles(Long userId) {
		//Long userId = AuthUtil.getUser().getUserId();
		List<Long> roleIds = baseMapper.getUserRoleIds(userId);
		String strroleIds = roleIds.stream().map(aLong -> aLong + "").collect(Collectors.joining(","));
		List<RoleVo> roles = baseMapper.getUserRoles(strroleIds);
		return roles;
	}

	/**
	 * 用户密码修改
	 *
	 * @param origPassword
	 * @param newPassword
	 * @param affirmPassword
	 * @return
	 */
	public boolean userPasswordEdit(String origPassword, String newPassword, String affirmPassword) {
		Long userId = AuthUtil.getUser().getUserId();
		//获取该用户的基本信息
		User user = getOne(Wrappers.<User>lambdaQuery().eq(User::getId, userId));
		//比较原始密码是否正确
		if (!passwordEncoder.matches(origPassword,user.getPassword())) {
			throw new ServiceException(PASSWORD_ORIG_ERROR);
		}
		//判断密码复杂性规则
		if (!Pattern.matches(PASSWORD_MATCHE, newPassword)) {
			throw new ServiceException(PASSWORD_MATCHE_ERROR);
		}
		//比较新密码与确认密码是否相同
		if (!newPassword.equals(affirmPassword)) {
			throw new ServiceException(PASSWORD_AFFIRM_ERROR);
		}
		//设置新密码保存
		user.setPassword(passwordEncoder.encode(affirmPassword));
		//记录更新人(其他地方会记录管理员更新记录)
		user.setUpdateUserid(userId);
		return updateById(user);
	}

	/**
	 * 用户密码重置
	 *
	 * @param userId
	 * @return
	 */
	public boolean userPasswordReset(Long userId) {
		Long updateUserId = AuthUtil.getUser().getUserId();
		User user = getOne(Wrappers.<User>lambdaQuery().eq(User::getId, userId));
		if (Objects.isNull(user)) {
			return false;
		}
		user.setPassword(passwordEncoder.encode(dfpassword));
		//记录更新人
		user.setUpdateUserid(updateUserId);
		return updateById(user);
	}




	/**
	 * 递归获取子级列表
	 *
	 * @param root
	 * @param all
	 * @return
	 */
	public static List<PermissionVo> getChildren(PermissionVo root, List<PermissionVo> all) {
		List<PermissionVo> children = all.stream().filter(t -> {
			return Objects.equals(t.getParentId(), root.getId());
		}).map(
			m -> {
				m.setChildren(getChildren(m, all));
				return m;
			}
		).collect(Collectors.toList());
		return children;
	}

}
